package com.yqq.common.filter;

import com.central.common.context.LoginUserContextHolder;
import com.central.common.model.LoginAppUser;
import com.central.common.utils.LoginUserUtils;
import jakarta.servlet.Filter;
import jakarta.servlet.FilterChain;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.core.annotation.Order;
import org.springframework.web.filter.OncePerRequestFilter;

import java.io.IOException;

/**
 * @ClassName LoginUserFilter
 * @Description 获取当前登录人过滤器
 * @author: zhijianpu
 * @Date: 2025/2/26
 */

/**
 * OncePerRequestFilter 是 Spring 框架提供的一个抽象类，
 * 用于确保在一次 HTTP 请求的生命周期内，特定的过滤器逻辑仅执行一次。
 * 这对于需要在请求处理前后进行一次性设置或清理资源的场景特别有用。
 *
 * 确保单次执行： OncePerRequestFilter 通过内部机制，确保在一次请求的生命周期内，
 * 过滤器的逻辑仅被执行一次，即使请求经过多次转发或包含多个资源请求。
 *
 * 支持异步请求： 默认情况下，OncePerRequestFilter 不会应用于异步请求。
 * 如果需要在异步请求中也应用该过滤器，
 * 需要重写 shouldNotFilterAsyncDispatch() 和 shouldNotFilterErrorDispatch() 方法。
 *
 */
@ConditionalOnClass(Filter.class)
@Order
public class LoginUserFilter extends OncePerRequestFilter {
    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
        try {
            LoginAppUser user = LoginUserUtils.getCurrentUser(request, false);
            LoginUserContextHolder.setUser(user);
            filterChain.doFilter(request, response);
        } finally {
            LoginUserContextHolder.clear();
        }
    }
}
